import Service.DeepSeekService;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

// 表示一个雇员节点
class Emp {
    public int id;
    public String name;
    public int age;
    public String gender;
    public Emp next;

    public Emp(int id, String name, int age, String gender) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}

// 创建EmpLinkedList，表示哈希表中的某个链表
class EmpLinkedList {
    // 头指针，直接指向第一个Emp，默认null
    private Emp head;

    // 添加雇员到链表（直接添加到尾部）
    public void add(Emp emp) {
        if (head == null) { // 即添加第一个雇员
            head = emp;
            return;
        }
        // 如果不是第一个雇员，则遍历链表找到尾指针
        Emp curEmp = head;
        while (true) {
            if (curEmp.next == null) {
                break;
            }
            curEmp = curEmp.next;
        }
        // 退出时直接将emp 加入链表
        curEmp.next = emp;
    }

    // 遍历链表的雇员信息
    public void list(int no) {
        if (head == null) { // 说明链表为空
            System.out.println("第" + no + "链表为空");
            return;
        }
        System.out.print("第" + no + "链表的信息为: ");
        Emp curEmp = head; // 辅助指针
        while (true) {
            System.out.printf("=>id=%d name=%s age=%d gender=%s\t", curEmp.id, curEmp.name, curEmp.age, curEmp.gender);
            if (curEmp.next == null) {
                break;
            }
            curEmp = curEmp.next;
        }
        System.out.println();
    }

    // 根据id查找雇员
    public Emp findEmpById(int id) {
        if (head == null) {
            System.out.println("链表为空");
            return null;
        }
        // 辅助指针
        Emp curEmp = head;
        while (true) {
            if (curEmp.id == id) {
                break; // 这时curEmp就指向要查找的雇员
            }
            // 退出
            if (curEmp.next == null) { // 说明遍历当前链表没有找到该雇员
                curEmp = null;
                break;
            }
            curEmp = curEmp.next;
        }
        return curEmp;
    }

    // 根据id删除雇员
    public boolean deleteEmpById(int id) {
        if (head == null) return false;
        if (head.id == id) {
            head = head.next;
            return true;
        }//检查头节点是否为目标节点
        Emp prev = head;
        Emp curEmp = head.next;
        while (curEmp != null) {
            if (curEmp.id == id) {
                prev.next = curEmp.next;
                return true;
            }
            prev = curEmp;
            curEmp = curEmp.next;
        }//遍历查找：使用双指针（prev和curEmp）遍历后续节点：
        return false;//遍历结束未找到则返回false。
    }

    // 根据年龄删除雇员
    public boolean deleteEmpByAge(int age) {
        if (head == null) return false;
        boolean deleted = false;

        // 删除头节点中年龄匹配的雇员
        while (head != null && head.age == age) {
            head = head.next;
            deleted = true;
        }

        Emp prev = head;
        Emp curEmp = head != null ? head.next : null;

        // 删除非头节点中年龄匹配的雇员
        while (curEmp != null) {
            if (curEmp.age == age) {
                prev.next = curEmp.next;
                deleted = true;
            } else {
                prev = curEmp;
            }
            curEmp = curEmp.next;
        }

        return deleted;
    }

    // 根据名字删除雇员
    public boolean deleteEmpByName(String name) {
        if (head == null) return false;
        boolean deleted = false;

        // 删除头节点中名字匹配的雇员
        while (head != null && head.name.equals(name)) {
            head = head.next;
            deleted = true;
        }

        Emp prev = head;
        Emp curEmp = head != null ? head.next : null;

        // 删除非头节点中名字匹配的雇员
        while (curEmp != null) {
            if (curEmp.name.equals(name)) {
                prev.next = curEmp.next;
                deleted = true;
            } else {
                prev = curEmp;
            }
            curEmp = curEmp.next;
        }

        return deleted;
    }

    // 按姓名片段查找雇员
    public List<Emp> findEmpsByName(String namePart) {
        List<Emp> result = new ArrayList<>();
        Emp curEmp = head;
        while (curEmp != null) {
            if (curEmp.name.contains(namePart)) { // 如果雇员名字包含用户输入的部分字符串
                result.add(curEmp); // 添加到结果列表
            }
            curEmp = curEmp.next;
        }
        return result; // 返回匹配到的所有雇员
    }
}

// 创建哈希表，管理多条链表
class HashTab {
    private EmpLinkedList[] empLinkedListArray;
    private int size; // 表示有多少个链表

    public HashTab(int size) {
        this.size = size;
        empLinkedListArray = new EmpLinkedList[size];
        for (int i = 0; i < size; i++) {
            empLinkedListArray[i] = new EmpLinkedList();
        }
    }

    // 添加雇员
    public void add(Emp emp) {
        // 根据员工的id，得到该员工应当添加到哪条链表
        int empLinkedListNO = emp.id % size;
        empLinkedListArray[empLinkedListNO].add(emp);
    }

    // 遍历所有的链表，遍历哈希表
    public void list() {
        for (int i = 0; i < size; i++) {
            empLinkedListArray[i].list(i);
        }
    }

    // 根据输入的id，查找雇员
    public void findEmpById(int id) {
        // 使用散列函数确定到哪条链表查找
        int empLinkedListNO = id % size;
        Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id);
        if (emp != null) { // 找到
            System.out.printf("在第%d条链表中找到雇员: id=%d, name=%s, age=%d, gender=%s\n", empLinkedListNO, id, emp.name, emp.age, emp.gender);
        } else {
            System.out.println("在哈希表中，没有找到该雇员~");
        }
    }

    // 根据id删除员工
    public void deleteEmpById(int id) {
        int empLinkedListNO = id % size;
        boolean deleted = empLinkedListArray[empLinkedListNO].deleteEmpById(id);//定位链表：通过哈希函数确定目标链表位置
        if (deleted) {//结果反馈：根据返回值提示操作结果：
            System.out.printf("已删除第%d条链表的雇员%d\n", empLinkedListNO, id);
        } else {
            System.out.println("删除失败，雇员不存在");
        }
    }

    // 根据年龄删除雇员
    public void deleteEmpByAge(int age) {
        boolean deleted = false;
        for (EmpLinkedList empLinkedList : empLinkedListArray) {
            if (empLinkedList.deleteEmpByAge(age)) {
                deleted = true;
            }
        }
        if (deleted) {
            System.out.printf("已删除所有年龄为%d的雇员\n", age);
        } else {
            System.out.println("删除失败，没有找到年龄匹配的雇员");
        }
    }

    // 根据名字删除雇员
    public void deleteEmpByName(String name) {
        boolean deleted = false;
        for (EmpLinkedList empLinkedList : empLinkedListArray) {
            if (empLinkedList.deleteEmpByName(name)) {
                deleted = true;
            }
        }
        if (deleted) {
            System.out.printf("已删除所有名字为%s的雇员\n", name);
        } else {
            System.out.println("删除失败，没有找到名字匹配的雇员");
        }
    }

    // 根据id，修改员工的姓名，年龄，性别
    public void updateEmp(int id, String newName, int newAge, String newGender) {
        int empLinkedListNO = id % size;//定位链表：通过id % size哈希到对应链表。
        Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id);//查找雇员：调用链表的findEmpById方法。
        if (emp != null) {//更新信息：若找到则直接修改属性：
            emp.name = newName;
            emp.age = newAge;
            emp.gender = newGender;
            System.out.printf("已更新雇员%d的信息\n", id);
        } else {
            System.out.println("更新失败，雇员不存在");
        }
    }

    // 模糊查找
    public void findEmpsByName(String namePart) {
        List<Emp> matchedEmps = new ArrayList<>();

        // 遍历哈希表中的所有链表
        for (EmpLinkedList empLinkedList : empLinkedListArray) {
            matchedEmps.addAll(empLinkedList.findEmpsByName(namePart)); // 合并所有匹配的雇员
        }

        if (!matchedEmps.isEmpty()) {
            System.out.println("匹配的雇员如下:");
            for (Emp emp : matchedEmps) {
                System.out.printf("id=%d, name=%s, age=%d, gender=%s\n", emp.id, emp.name, emp.age, emp.gender);
            }
        } else {
            System.out.println("没有找到匹配的雇员");
        }
    }
}

public class HashTabDemo {

    static int count = 1;
    static HashTab hashTab = new HashTab(10);
    static MyClassLoader loader;

    public void doMain(MyClassLoader loader1) {
        loader = loader1;
        Scanner scanner = new Scanner(System.in);
        System.out.println(HashTabDemo.class.getClassLoader().toString());

        hashTab.add(new Emp(101, "张三", 23, "男"));
        hashTab.add(new Emp(102, "张伟", 25, "男"));
        hashTab.add(new Emp(103, "李四", 22, "男"));
        hashTab.add(new Emp(104, "李雷", 26, "男"));
        hashTab.add(new Emp(105, "王五", 27, "男"));
        hashTab.add(new Emp(106, "王小明", 22, "男"));
        hashTab.add(new Emp(107, "赵六", 23, "男"));
        hashTab.add(new Emp(108, "赵云", 24, "男"));
        hashTab.add(new Emp(109, "陈奕迅", 21, "男"));
        hashTab.add(new Emp(110, "陈小春", 23, "男"));

        int menu = 0;
        DeepSeekService ds = new DeepSeekService();

        while (menu != 8) {
            System.out.println("------1:添加 2:显示 3:查找 4:删除 5:修改 6:AI操作 7:退出------");
            menu = scanner.nextInt();
            switch (menu) {
                case 1:
                    System.out.print("输入id: ");
                    int id = scanner.nextInt();
                    System.out.print("输入姓名: ");
                    String name = scanner.next();
                    System.out.print("输入年龄: ");
                    int age = scanner.nextInt();
                    System.out.print("输入性别: ");
                    String gender = scanner.next();
                    hashTab.add(new Emp(id, name, age, gender));
                    break;
                case 2:
                    hashTab.list();
                    break;
                case 3:
                    this.search();
                    break;
                case 4:
                    this.delete();
                    break;
                case 5:
                    System.out.print("输入修改id: ");
                    int updateId = scanner.nextInt();
                    System.out.print("输入新姓名: ");
                    String newName = scanner.next();
                    System.out.print("输入新年龄: ");
                    int newAge = scanner.nextInt();
                    System.out.print("输入新性别: ");
                    String newGender = scanner.next();
                    hashTab.updateEmp(updateId, newName, newAge, newGender);
                    break;
                case 6:
                    scanner.nextLine();
                    System.out.println("用文字描述需要执行的操作：");
                    String statement = ds.call(
                            "你的身份是作为我的哈希表项目的机器人，" +
                                    "你需要根据我的需求给出对应函数的调用的执行代码，" +
                                    "不需要补全代码,不需要解释，" +
                                    "只返回一行代码给我，" +
                                    "例如我要新增一个职员：id是10，名字叫张三，年龄是18，性别是男。你只需要返回一行代码，HashTabDemo.hashTab.add(new Emp(1,张三,18,男));" +
                                    "删除id是2的员工：HashTabDemo.hashTab.deleteEmpById(2);" +
                                    "修改id为1的员工 名字修改为张三，年龄修改为23，性别修改为男：HashTabDemo.hashTab.updateEmp(1,张三,23,男);" +
                                    "查询所有员工：HashTabDemo.hashTab.list();" +
                                    "查询id是3的员工：HashTabDemo.hashTab.findEmpById(int id);" +
                                    "查询姓名是张三的员工：HashTabDemo.hashTab.findEmpsByName(String.ValueOf(张三));" +
                                    "现在我给你下指令：" + scanner.nextLine()
                    );
                    try {
                        justDoIt(statement);
                    } catch (MalformedURLException | ClassNotFoundException | IllegalAccessException |
                            InstantiationException | InvocationTargetException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case 7:
                    System.out.println("退出系统");
                    break;
                default:
                    System.out.println("输入错误");
            }
        }
    }

    public void delete() {
        Scanner scanner = new Scanner(System.in);
        int menu = 0;
        while (menu != 4) {
            System.out.println("------1:按ID删除 2:按年龄删除 3:按名字删除 4:退出------");
            menu = scanner.nextInt();
            switch (menu) {
                case 1:
                    System.out.print("输入删除id: ");
                    hashTab.deleteEmpById(scanner.nextInt());
                    break;
                case 2:
                    System.out.print("输入删除年龄: ");
                    hashTab.deleteEmpByAge(scanner.nextInt());
                    break;
                case 3:
                    System.out.print("输入删除名字: ");
                    String name = scanner.next();
                    hashTab.deleteEmpByName(name);
                    break;
                case 4:
                    break;
                default:
                    System.out.println("输入错误");
                    break;
            }
        }
    }

    public void search() {
        Scanner scanner = new Scanner(System.in);
        int menu = 0;
        while (menu != 5) {
            System.out.println("------1:按ID查找 2:按姓名查找 5:退出------");
            menu = scanner.nextInt();
            switch (menu) {
                case 1:
                    System.out.print("输入查找id: ");
                    hashTab.findEmpById(scanner.nextInt());
                    break;
                case 2:
                    System.out.println("请输入姓名关键词:");
                    String namePart = scanner.next();
                    hashTab.findEmpsByName(namePart);
                    break;
                case 5:
                    break;
                default:
                    System.out.println("输入错误");
                    break;
            }
        }
    }

    public static void justDoIt(String statement) throws MalformedURLException, InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException {
        System.out.println("执行指令：" + statement);
        System.out.println();
        String className = "TempClass" + count++;
        String code = "public class " + className + " {public void invoke() { " + statement + " }}";
        // 获取目录
        File tempDir = new File(System.getProperty("java.io.tmpdir"));
        File file = new File(tempDir, className + ".java"); // 文件名必须与类名一致
        try (FileWriter writer = new FileWriter(file)) {
            writer.write(code);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        compiler.run(null, null, null, file.getPath());

        // 在自定义加载器中公开暴露URLClassLoader的私有函数addURL
        loader.addURL(tempDir.toURI().toURL());

        try {
            // 加载临时类
            loader.loadClass(className);
            // 加载 TempClass
            Class<?> cla = Class.forName(className, true, loader);

            // 获取构造函数并设置可访问
            Constructor<?> constructor = cla.getDeclaredConstructor();
            constructor.setAccessible(true); // 允许访问包级私有构造函数

            // 创建实例并调用方法
            Object obj = constructor.newInstance();
            Method print = cla.getMethod("invoke");
            print.invoke(obj);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } finally {
            // 清理临时文件
            file.deleteOnExit();
            new File(tempDir, className + ".class").deleteOnExit();
        }
    }

    public static void main(String[] args) {
        new HashTabDemo().doMain(loader);
    }
}